<template>
  <div>
    <el-card>
      <el-button type="primary" icon="el-icon-plus" @click="handleAddRole">新增</el-button>
      <el-table :data="roleList" style="width: 100%; margin-top: 20px" border>
        <el-table-column type="expand">
          <template #default="scope">
            <div v-if="scope.row.menus_tree_list.length>0">
              <el-row v-for="(m,index) in scope.row.menus_tree_list" :key="m.id"
                      :class="['bottom',index === 0?'top':'']"
              >
                <el-col :span="8">
                  <el-tag closable @click="removeMenu(scope.row,m.id)">{{ m.name }}</el-tag>
                  <i class="el-icon-caret-right"/>
                </el-col>
                <el-col :span="12">
                  <el-tag
                    v-for="mc in m.children"
                    :key="mc.id"
                    closable
                    type="success"
                    @click="removeMenu(scope.row,mc.id)"
                  >{{ mc.name }}
                  </el-tag>
                </el-col>
              </el-row>
            </div>
            <div v-else>
              <el-empty :image-size="80" description="暂无权限"/>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="序号" type="index" align="center" width="50px"/>
        <el-table-column label="角色名称" prop="name" align="center"/>
        <el-table-column label="角色详情" prop="desc" align="center"/>
        <el-table-column label="操作" align="center">
          <template v-slot="scope">
            <el-button size="mini" type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
            <el-popconfirm
              icon="el-icon-info"
              icon-color="red"
              title="确定删除此角色吗？"
              @confirm="delRoleBtn(scope.row)"
            >
              <template #reference>
                <el-button style="margin:0 10px " size="mini" type="danger" icon="el-icon-delete">删除</el-button>
              </template>
            </el-popconfirm>
            <el-button size="mini" type="warning" icon="el-icon-setting" @click="handleSet(scope.row)">分配权限
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        :current-page="page"
        :page-sizes="[5, 10, 20]"
        :page-size="pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        style="margin-top: 20px"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>

    <!-- 新增或编辑角色弹框-->
    <el-dialog
      :title="addRoleOrEditForm.id?'编辑角色' : '新增角色'"
      :visible.sync="addRoleOrEditVisible"
      width="30%"
      :before-close="addRoleOrEditClose"
    >
      <el-form ref="addRoleOrEditForm" :model="addRoleOrEditForm" :rules="addRoleOrEditRules" label-width="80px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="addRoleOrEditForm.name" placeholder="请输入角色名称"/>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="addRoleOrEditForm.desc" placeholder="请输入角色名称"/>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addRoleOrEditClose">取 消</el-button>
        <el-button type="primary" @click="addRoleOrEditRole">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 分配角色弹框 -->
    <el-dialog title="分配权限" :visible.sync="setMenuVisible" width="30%" :before-close="handleMenuClose">
      <el-tree
        ref="treeRef"
        :data="menuList"
        :props="menuProps"
        show-checkbox
        :default-checked-keys="checkedNode"
        :default-expand-all="true"
        node-key="id"
      />
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleMenuClose">取 消</el-button>
        <el-button type="primary" @click="setMenu">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
import { role, delMenu, setRoleMenu, addRole, editRole, delRole } from '@/api/role'
import { menu } from '@/api/menu'

export default {
  name: 'RoleList',
  data() {
    return {
      roleList: [],
      setMenuVisible: false,
      page: 1,
      pagesize: 5,
      total: 0,
      menuList: [],
      menuProps: {
        children: 'children',
        label: 'name'
      },
      checkedNode: [], // 用户选中的节点
      roleId: null,
      addRoleOrEditVisible: false, // 控制新增或者编辑角色弹框关闭
      addRoleOrEditForm: {
        name: '',
        desc: ''
      },
      addRoleOrEditRules: {
        name: [
          { required: true, message: '请输入角色名称', trigger: 'blur' },
          { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
        ]
      }

    }
  },
  created() {
    this.getRoleList()
    this.getMenuList()
  },
  methods: {
    // 获取角色列表
    async getRoleList() {
      const res = await role({ page: this.page, pagesize: this.pagesize })
      if (res.code !== 200) return this.$message.error(res.msg)
      this.roleList = res.data.lists
      this.total = res.data.total
    },
    // 删除角色下的权限
    async removeMenu(row, mid) {
      const result = await this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).catch((e) => e)
      if (result === 'cancel') return this.$message.info('取消删除操作！')
      try {
        const res = await delMenu(row.id, mid)
        if (res.status !== 200) return this.$message.error('删除角色失败！')
        this.$message.success('删除角色成功！')
        console.log(row.menu)
        // eslint-disable-next-line require-atomic-updates
        row.menu = res.data
      } catch (error) {
        console.log(error)
      }
    },
    // 新增角色按钮
    handleAddRole() {
      this.addRoleOrEditForm = {
        name: '',
        desc: ''
      }
      this.addRoleOrEditVisible = true
    },
    // 编辑角色按钮
    handleEdit(row) {
      this.addRoleOrEditVisible = true
      Object.assign(this.addRoleOrEditForm, row)
    },
    // 新增或角色弹框关闭的回调
    addRoleOrEditClose() {
      this.addRoleOrEditVisible = false
      this.$refs.addRoleOrEditForm.resetFields()
    },
    // 新增或编辑角色确定按钮
    async addRoleOrEditRole() {
      if (this.addRoleOrEditForm.id) {
        // 编辑操作
        const res = await editRole(this.addRoleOrEditForm.id, this.addRoleOrEditForm)
        if (res.code !== 200) return this.$message.error('编辑角色失败！')
      } else {
        // 新增操作
        const res = await addRole(this.addRoleOrEditForm)
        if (res.code !== 201) return this.$message.error('新增角色失败！')
      }
      this.addRoleOrEditClose()
      this.$message.success(this.addRoleOrEditForm.id ? '编辑角色成功' : '新增角色成功')
      this.getRoleList()
    },
    // 删除角色
    async delRoleBtn(row) {
      const res = await delRole(row.id)
      if (res.code !== 200) return this.$message.error('删除角色失败！')
      this.$message.success('删除角色成功!')
      this.getRoleList()
    },
    // 分配角色
    handleSet(row) {
      this.getMenuList()
      this.setMenuVisible = true
      this.getMenuNode(row.menus_list)
      this.roleId = row.id
    },
    // 分配角色弹框关闭的回调
    handleMenuClose() {
      this.checkedNode = []
      this.setMenuVisible = false
    },
    // 获取树形菜单
    async getMenuList() {
      const res = await menu('tree')
      if (res.code !== 200) return this.$message.error('获取菜单列表失败！')
      this.menuList = res.data.data
    },
    // 获取单个角色权限的菜单集合
    getMenuNode(menus) {
      menus.forEach(item => {
        if (item.pid) {
          this.checkedNode.push(item.id)
        }
      })
    },
    // 设置角色弹框确定按钮
    async setMenu() {
      const checkList = [...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys()]
      const res = await setRoleMenu({ rid: this.roleId, mid: checkList })
      if (res.code !== 200) return this.$message.error('设置角色权限失败！')
      this.$message.success('设置角色权限成功！')
      this.handleMenuClose()
      this.getMenuList()
      this.getRoleList()
    },
    // 当前页数发生变化的回调
    handleSizeChange(val) {
      this.pagesize = val
      this.getRoleList()
    },
    // 当前页数发生变化的函数
    handleCurrentChange(val) {
      this.page = val
      this.getRoleList()
    }
  }

}
</script>

<style scoped>
.top {
  border-top: 1px solid #ccc;
}

.bottom {
  border-bottom: 1px solid #ccc;
}

.el-tag {
  margin: 10px;
  cursor: pointer;
}
</style>
